<template>
  <a-modal
    v-model:visible="visible"
    :title="modalTitle"
    :width="modalWidth"
    :maskClosable="false"
    :destroyOnClose="true"
    wrapClassName="custom-modal min-base-modal"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <a-row :gutter="24">
      <a-col :span="13">
        <a-form
          ref="formRef"
          inline
          :model="formData"
          :rules="rules"
          v-bind="formItemLayout"
        >
          <a-form-item label="部件名称" name="partId" required>
            <a-select
              v-model:value="formData.partId"
              allow-clear
              @change="handleSelectChange"
              placeholder="请选择部件名称"
              :options="selectList"
              :fieldNames="{
                value: 'partId',
                label: 'partName'
              }"
            />
          </a-form-item>
          <a-form-item label="关联NVR名称" name="nvrId" required>
            <a-select
              v-model:value="formData.nvrId"
              allow-clear
              placeholder="请选择关联NVR名称"
              @change="handleChangeNvr"
              :options="nvrList"
              :fieldNames="{
                label: 'name',
                value: 'id'
              }"
            />
          </a-form-item>
          <a-form-item label="关联摄像机" name="cameraId" required>
            <a-select
              v-model:value="formData.cameraId"
              allow-clear
              placeholder="请选择关联摄像机"
              @change="handleChangeCamera"
              :options="cameraList"
              :fieldNames="{
                label: 'name',
                value: 'id'
              }"
            />
          </a-form-item>
          <!-- 摄像机是枪机时，关联预置位名称不显示/禁用 -->
          <a-form-item
            label="关联预置位名称"
            name="positionName"
            v-if="+pointData.type !== 2"
            :required="+pointData.type !== 2"
          >
            <a-select
              v-model:value="formData.positionName"
              allow-clear
              placeholder="请选择关联预置位名称"
              @change="handleChangePoint"
              :options="pointList"
              :fieldNames="{
                label: 'positionName',
                value: 'positionName'
              }"
            />
          </a-form-item>
        </a-form>
        <a-row>
          <a-col :span="12">
            <span class="text-[#4E5969]">预置位抓拍：</span>
            <a-button
              type="link"
              @click="handleCamera"
              :disabled="zhuapai || isZp"
            >
              {{ !zhuapai ? '抓拍图片' : '抓拍中...' }}
            </a-button>
          </a-col>
          <!-- <a-col :span="12">
            <span class="text-[#4E5969]">预置位标定：</span>
            <a-button type="link" disabled>标定</a-button>
          </a-col> -->
        </a-row>
        <a-row class="mt-2">
          <a-image
            height="16.4rem"
            :src="pointData.imageUrl"
            v-if="pointData.imageUrl"
          />
          <div v-else class="flex justify-center w-full">
            <a-empty :image="simpleImage">
              <template #description>
                <span> 暂无图片 </span>
              </template>
            </a-empty>
          </div>
        </a-row>
      </a-col>
      <a-col :span="11">
        <!-- <div>
          巡视点位映射三维视场角
          <a-button type="submit" @click="getThreeAngle">
            巡视点位映射
          </a-button>
          <span
            :class="['tips', formData.threeDimensionalParam ? 'has' : 'not']"
          >
            {{ formData.threeDimensionalParam ? '已配置' : '未配置' }}
          </span>
        </div> -->
        <div class="flex items-center justify-between">
          算法类别选择：
          <a-select
            style="width: 63%"
            v-model:value="formData.algType"
            allow-clear
            placeholder="请选择"
            @change="handleChangeAlg"
            :options="algList"
          />
        </div>
        <div class="bg-[#f7f8fa] rounded mt-2 px-3 py-3">
          <div v-if="formData.algType === '1'">
            <a-checkbox-group v-model:value="formData.checkbox">
              <a-row v-for="item in byAlgList" :key="item" class="mb-2">
                <a-checkbox :value="item.instanceName">
                  {{ item.instanceDesc }}
                </a-checkbox>
              </a-row>
            </a-checkbox-group>
          </div>
          <div v-if="formData.algType === '2'">
            <a-radio-group v-model:value="formData.radio">
              <a-row v-for="item in byAlgList" :key="item" class="mb-2">
                <a-radio :value="item.instanceName" @change="handleRadioChange">
                  {{ item.instanceDesc }}
                </a-radio>
              </a-row>
            </a-radio-group>
            <a-row :gutter="12" v-if="formData.radio">
              <a-col :span="12">
                <a-input-number
                  v-model:value="formData.floor"
                  min="0"
                  max="1"
                  step="0.05"
                  :addon-after="raType === 'JCQ' ? 'mA' : ''"
                  :parser="(value: any) => Math.ceil(value * 100) / 100"
                >
                  <!-- :parser="
                    (value) =>
                      value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
                  " -->
                  <template #addonBefore>下限</template>
                </a-input-number>
              </a-col>
              <a-col :span="12">
                <a-input-number
                  v-model:value="formData.upper"
                  min="0"
                  max="1"
                  step="0.05"
                  :addon-after="raType === 'JCQ' ? 'mA' : ''"
                  :parser="
                    (value: any) =>
                      String(value).replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')
                  "
                >
                  <template #addonBefore>上限</template>
                </a-input-number>
              </a-col>
            </a-row>
          </div>
        </div>
      </a-col>
    </a-row>

    <!-- <ThreeAngle ref="threeAngleRef" :data="formData" @confirm="submitAngle" /> -->

    <template #footer>
      <a-button class="cancel" @click="handleCancel">取消</a-button>
      <a-button
        key="submit"
        type="primary"
        :loading="loading"
        @click="handleOk"
        class="common-buttom"
      >
        确认
      </a-button>
    </template>
  </a-modal>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { message, Empty } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/es/form'

// import ThreeAngle from '../ThreeAngle.vue'

import {
  nvr,
  camera,
  point,
  pointCamera,
  algType,
  byAlgType,
  save
} from './serve.api'

const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE

// const threeAngleRef = ref()

const emit = defineEmits(['isOk'])

const visible = ref<boolean>(false)
const loading = ref<boolean>(false)

const zhuapai = ref<boolean>(false)
const isZp = ref<boolean>(true) // 是否可以抓拍

const modalTitle = ref('')
const modalType = ref('')
const modalWidth = ref('')
const modalData = ref()

const formState = ref({})
const pointData = ref({
  type: '',
  nvrIp: '',
  passNum: '',
  positionNum: '',
  nvrPort: '',
  nvrUsername: '',
  nvrPassword: '',
  manufacturer: '',
  imageUrl: ''
})

const nvrList = ref<any[]>([])
const cameraList = ref<any[]>([])
const pointList = ref<any[]>([])
const algList = ref<any[]>([])
const byAlgList = ref<any[]>([])

defineProps({
  selectList: {
    type: Array,
    default: () => []
  }
})

interface FormData {
  nvrId?: undefined | string
  partId?: undefined | string
  cameraId?: undefined | string
  positionName?: undefined | string
  algType?: undefined | string
  checkbox?: undefined | string[]
  radio?: undefined | string
  floor?: undefined | string
  upper?: undefined | string

  id?: undefined | string
  partName: string
  deviceId: string
  deviceName: string
  isMultiplePatrol: number | string
  // threeDimensionalParam?: string
}

const formRef = ref()
const formData = reactive<FormData>({
  nvrId: undefined,
  partId: undefined,
  cameraId: undefined,
  positionName: undefined,
  algType: '1',
  checkbox: [], // 算法类别(多选缺陷算法)
  radio: '', // 算法类别选择(单选表计数算法)
  floor: '', // 下限
  upper: '', // 上限

  id: undefined,
  partName: '',
  deviceId: '',
  deviceName: '',
  isMultiplePatrol: ''
  // threeDimensionalParam: '' // 巡视点映射三维视场角
})

const formItemLayout = {
  labelCol: { span: 7 },
  wrapperCol: { span: 24 }
}

const rules: Record<string, Rule[]> = {}

// 选择部件名称
function handleSelectChange(item: any, options: any) {
  formData.partId = options.partId
  formData.partName = options.partName
  formData.deviceId = options.deviceId
  formData.deviceName = options.deviceName
}

// NVR列表
function nvrFun() {
  nvr().then((res: any) => {
    console.log(res, 'nvr')
    nvrList.value = res
  })
}

// 选择NVR时，获取摄像机列表
const handleChangeNvr = async (value: any, options: any) => {
  console.log(options, 'nvr')
  formData.cameraId = undefined // 选择NVR时，清空摄像机
  formData.positionName = undefined // 选择NVR时，清空预置位

  pointData.value.nvrIp = options.ip
  pointData.value.nvrPort = options.port
  pointData.value.nvrUsername = options.userName
  pointData.value.nvrPassword = options.password
  pointData.value.manufacturer = options.manufacturer

  cameraList.value = await camera({ nvrId: value })
}

// 选择摄像机时，获取预置位列表
const handleChangeCamera = async (value: any, options: any) => {
  console.log(options, 'camera')
  formData.positionName = undefined // 选择摄像机时，清空预置位
  pointData.value.imageUrl = '' // 选择摄像机时，清空图片

  pointData.value.passNum = options.passNum
  pointData.value.type = options.type // 相机类型
  if (+options.type === 2) {
    // TODO 摄像机类型：枪机
    isZp.value = false
    pointData.value.positionNum = ''
  } else {
    isZp.value = true
  }

  pointList.value = await point({
    nvrIp: pointData.value.nvrIp,
    cameraIp: options.ip
  })
}

// 选择预置位时，获取预置位名称
const handleChangePoint = (value: any, options: any) => {
  console.log(options, 'point')
  isZp.value = false

  pointData.value.positionNum = options.positionNum
}

// 抓拍图片
function handleCamera() {
  console.log('抓拍图片', pointData.value)
  zhuapai.value = true

  pointCamera(pointData.value).then((res: any) => {
    if (res) {
      zhuapai.value = false
      pointData.value.imageUrl = res
      message.success('抓拍成功')
    } else {
      message.error('抓拍失败')
      zhuapai.value = false
    }
  })
}

// 获取三维映射视场角
// function getThreeAngle() {
//   threeAngleRef.value.showModal(formData)
// }

// 算法类型
function algTypeFun() {
  algType().then((res: any) => {
    console.log(res, '算法类型')
    if (res) {
      algList.value = res
    }
  })
}

function byAlgTypeFun(algType: string) {
  byAlgType({ algType }).then((res: any) => {
    console.log(res, '算法类型实例')
    if (res) {
      byAlgList.value = res
    }
  })
}

function handleChangeAlg(value: any, options: any) {
  console.log(value, options)

  formData.checkbox = undefined
  formData.radio = undefined
  formData.floor = ''
  formData.upper = ''

  formData.algType = value
  byAlgTypeFun(options.label)
}

// 切换单选
const raType = ref('')
function handleRadioChange(item: any) {
  raType.value = item.target.value
  formData.floor = ''
  formData.upper = ''
}

// 获取视场角
// function submitAngle(item: any) {
//   formData.threeDimensionalParam = item
// }

const showModal = (type: string, data?: any) => {
  visible.value = true
  modalType.value = type
  modalData.value = data
  console.log(data, 'data')

  switch (type) {
    case 'add':
      modalTitle.value = '添加巡视点位'
      modalWidth.value = '58.25rem'
      formState.value = {}

      formData.partId = undefined
      formData.partName = ''
      formData.deviceId = ''
      formData.deviceName = ''

      formData.nvrId = undefined
      formData.cameraId = undefined

      cameraList.value = []
      pointList.value = []

      byAlgTypeFun('变电缺陷算法') // 获取算法类别类型实例

      nvrFun() // 获取NVR列表
      algTypeFun() // 获取算法类别类型
      break
    case 'edit':
      modalTitle.value = '编辑巡视点位'
      modalWidth.value = '58.25rem'
      formState.value = {}

      // 判断是否已有提交数据(有提交)
      if (data?.nvrId || data?.cameraId) {
        console.log('已')
        formData.id = data?.id
        formData.partId = data?.partId
        formData.partName = data?.partName
        formData.deviceId = data?.deviceId
        formData.deviceName = data?.deviceName
        formData.isMultiplePatrol = data?.isMultiplePatrol

        formData.nvrId = data.nvrId // 赋值NVR名称

        camera({ nvrId: data.nvrId }).then((res) => {
          if (res) {
            cameraList.value = res
            formData.cameraId = data.cameraId // 赋值摄像机名称
          }
        })

        // 判断是否有预置位名称(根据相机类型 1云台 2枪机)
        if (data?.cameraType) {
          pointData.value.type = data?.cameraType // 赋值相机类型

          point({
            nvrIp: data?.nvrIp,
            cameraIp: data?.cameraIp
          }).then((res) => {
            pointList.value = res
            formData.positionName = data.positionName // 赋值预置位名称
          })

          if (+data?.cameraType === 2) {
            isZp.value = false
          } else {
            isZp.value = true
          }
        }

        // 判断是否有抓拍图片
        if (data?.positionPic) {
          zhuapai.value = false
          pointData.value.imageUrl = data.positionPic // 赋值抓拍图片
        }
        // TODO 赋值抓拍图片需要的参数
        pointData.value.nvrIp = data.nvrIp
        pointData.value.nvrPort = data.nvrPort
        pointData.value.nvrUsername = data.nvrUsername
        pointData.value.nvrPassword = data.nvrPassword
        pointData.value.positionNum = data.positionNum
        pointData.value.manufacturer = data.manufacturer
        pointData.value.passNum = data.passNum

        isZp.value = false // 在详情里，除了未提交数据，其他都可抓拍图片

        // formData.threeDimensionalParam = JSON.parse(data.threeDimensionalParam) // 赋值巡视点映射三维视场角

        // 判断算法类别类型(变电缺陷，变电表计读数)
        if (data?.floor || data?.upper) {
          formData.algType = '2' // 赋值(单选)表计读数类型
          console.log(data, '=====')
          formData.radio = data.algInstance
          formData.floor = data.floor // 赋值下限
          formData.upper = data.upper // 赋值上限
          byAlgTypeFun('变电表计读数')
        } else {
          formData.algType = '1' // 赋值(多选)变电缺陷类型
          formData.checkbox = data.algInstance.split(',')
          byAlgTypeFun('变电缺陷算法')
        }
      } else {
        console.log('未')
        formData.nvrId = undefined
        formData.cameraId = undefined

        formData.partId = undefined
        formData.partName = ''
        formData.deviceId = ''
        formData.deviceName = ''

        cameraList.value = []
        pointList.value = []

        byAlgTypeFun('变电缺陷算法') // 获取算法类别类型实例
      }

      nvrFun() // 获取NVR列表
      algTypeFun() // 获取算法类别类型
      break
    default:
      break
  }
}

const handleOk = async () => {
  try {
    await formRef.value.validateFields()
    if (modalType.value === 'add') {
      addFun()
    } else if (modalType.value === 'edit') {
      editFun()
    } else {
      message.error('表单填写不完整，请检查！')
    }
  } catch (error) {
    console.log('Failed:', error)
  }
}

// 提交参数判断
function validateParamsFields() {
  const params = {
    partId: formData.partId || '',
    partName: formData.partName,
    deviceId: formData.deviceId,
    deviceName: formData.deviceName,

    id: modalData.value?.id ?? '',
    nvrId: formData.nvrId,
    cameraId: formData.cameraId,
    positionNum: pointData.value.positionNum,
    positionName: formData.positionName,
    positionPic: pointData.value.imageUrl,
    // threeDimensionalParam: JSON.stringify(formData.threeDimensionalParam),
    algInstance: formData.checkbox?.length
      ? formData.checkbox!.join(',')
      : formData.radio,
    floor: formData.floor,
    upper: formData.upper
  }

  if (!params.algInstance) {
    message.warning('请选择算法类别类型')
    return
  }

  if (formData.radio) {
    if (params.floor === '' || params.upper === '') {
      message.warning('下限值和上限值不能为空')
      return
    }
    if (params.floor >= params.upper) {
      message.warning('下限值不能大于或等于上限值')
      return
    }
  }

  return params
}

// 添加
const addFun = async () => {
  // console.log(formData, 'formData')
  // console.log(pointData.value, 'pointData')
  // console.log(modalData.value, 'modalData')

  const params = await validateParamsFields()
  console.log(params, '提交添加参数集')

  if (params) {
    loading.value = true
    save(params, false)
      .then(() => {
        message.success('添加成功')
        emit('isOk')
        handleCancel()
        loading.value = false
        visible.value = false
      })
      .catch(() => {
        loading.value = false
      })
  }
}

// 编辑
const editFun = async () => {
  const params = await validateParamsFields()
  console.log(params, '提交编辑参数集')

  if (params) {
    loading.value = true
    save(params, true)
      .then(() => {
        message.success('修改成功')
        emit('isOk')
        handleCancel()
        loading.value = false
        visible.value = false
      })
      .catch(() => {
        loading.value = false
      })
  }
}

// 取消
const handleCancel = () => {
  visible.value = false
  pointData.value.type = ''
  pointData.value.nvrIp = ''
  pointData.value.passNum = ''
  pointData.value.positionNum = ''
  pointData.value.nvrPort = ''
  pointData.value.nvrUsername = ''
  pointData.value.nvrPassword = ''
  pointData.value.manufacturer = ''
  pointData.value.imageUrl = ''

  // formData.threeDimensionalParam = undefined
  formData.checkbox = undefined
  formData.radio = undefined
  formData.algType = '1'
  formData.floor = ''
  formData.upper = ''

  isZp.value = true

  formRef.value?.resetFields()
}

defineExpose({ showModal })
</script>

<style lang="less" scoped>
.tips {
  padding: 0.125rem 0.25rem;
  margin-left: 0.625rem;
  font-size: 0.75rem;
  border-radius: 0.125rem;
  line-height: 1;
}

.has {
  color: #00796a;
  background-color: #00796a10;
  border: 0.0625rem solid #00796a;
}

.not {
  color: #86909c;
  background-color: #86909c10;
  border: 0.0625rem solid #86909c;
}
</style>
